home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
c
/
nos042_s
/
ttydriv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-16
|
4KB
|
227 lines
/* TTY input line editing
* Copyright 1991 Phil Karn, KA9Q
*
* ATARI Version by David Nash - dnash@chaos.demon.co.uk
*/
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "session.h"
#include "tty.h"
#include "socket.h"
extern FILE *Rawterm;
#define OFF 0
#define ON 1
#define LINESIZE 256
#ifndef ATARI
#define CTLU 21
#define CTLR 18
#define CTLZ 26
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define HOME 71
#define END 334
#define BS 0x7f
#define DEL 83
#else
#define CTLU 21
#define CTLR 18
#define CTLZ 26
#define LEFT 330
#define RIGHT 332
#define UP 327
#define DOWN 335
#define HOME 326
#define END 334
#define BS 0x7f
#define DEL 338
#endif
/* Accept characters from the incoming tty buffer and process them
* (if in cooked mode) or just pass them directly (if in raw mode).
*
* Echoing (if enabled) is direct to the raw terminal. This requires
* recording (if enabled) of locally typed info to be done by the session
* itself so that edited output instead of raw input is recorded.
*/
struct mbuf *ttydriv(
struct session *sp,
int c )
{
struct mbuf *bp;
char *cp,*rp, cc;
int dif, i;
cc = c % 256;
switch(sp->ttystate.edit) {
case OFF:
bp = ambufw(1);
*bp->data = cc;
bp->cnt = 1;
if(sp->ttystate.echo)
putc(c,Rawterm);
return bp;
case ON:
if(sp->ttystate.line == NULLBUF)
sp->ttystate.line = ambufw(LINESIZE);
bp = sp->ttystate.line;
cp = bp->data + sp->cur_pos;
dif = bp->cnt - sp->cur_pos;
/* Perform cooked-mode line editing */
switch(c) {
case '\r': /* CR & LF both terminate line */
case '\n':
if(sp->ttystate.crnl)
*(cp + dif) = '\n';
else
*(cp + dif) = cc;
if(sp->ttystate.echo)
fputs(Eol,Rawterm);
bp->cnt += 1;
sp->ttystate.line = NULLBUF;
return bp;
case DEL:
#if 0
if (dif == 0)
break;
/* Forward a character */
sp->cur_pos++;
dif--;
cp++;
putc(' ', Rawterm);
#endif
if (sp->cur_pos < bp->cnt) {
sp->cur_pos++;
}
/* Now drop through to delete backwards */
case BS:
case '\b': /* Character delete */
if(sp->cur_pos) {
bp->cnt--;
sp->cur_pos--;
if(sp->ttystate.echo)
fputs("\b \b",Rawterm);
if (dif) {
memmove(cp - 1, cp, dif);
if(sp->ttystate.echo) {
for (i = 0; i < dif; i++)
putc(*(cp + i - 1), Rawterm);
putc(' ', Rawterm);
for (i = 0; i <= dif; i++)
fputs("\b", Rawterm);
}
}
}
break;
case CTLR: /* print line buffer */
if(sp->ttystate.echo)
{
fprintf(Rawterm,"^R%s",Eol);
rp = bp->data;
while (rp < cp)
putc(*rp++,Rawterm);
}
break ;
case CTLU: /* Line kill */
while (dif--)
putc(' ', Rawterm);
while(bp->cnt != 0) {
bp->cnt--;
if(sp->ttystate.echo)
fputs("\b \b",Rawterm);
}
sp->cur_pos = 0;
break;
case LEFT: /* Cursor left */
if (sp->cur_pos > 0) {
sp->cur_pos--;
fputs("\b",Rawterm);
}
break;
case RIGHT: /* Cursor right */
if (sp->cur_pos < bp->cnt) {
sp->cur_pos++;
if(sp->ttystate.echo)
putc(*cp, Rawterm);
}
break;
case HOME: /* Back to start of line */
while (sp->cur_pos) {
sp->cur_pos--;
if(sp->ttystate.echo)
fputs("\b", Rawterm);
}
break;
case END: /* Go to end of line */
for (i = 0; i < dif; i++) {
if(sp->ttystate.echo)
putc(*(cp + i), Rawterm);
sp->cur_pos++;
}
break;
case UP: /* Previous line */
break;
case DOWN: /* Next line */
break;
default: /* Ordinary character */
if (dif)
memmove(cp + 1, cp, dif);
*cp = cc;
bp->cnt++;
sp->cur_pos++;
if (sp->ttystate.echo && bp->cnt < LINESIZE-1) {
putc(cc,Rawterm);
if (dif) {
for (i = 0; i < dif; i++)
putc(*(cp + i + 1), Rawterm);
for (i = 0; i < dif; i++)
fputs("\b", Rawterm);
}
}
else if(bp->cnt >= LINESIZE-1) {
putc('\007',Rawterm); /* Beep */
bp->cnt--;
}
break;
}
break;
}
return NULLBUF;
}